package com.sixbro.shiro.jwt.controller;

import com.alibaba.fastjson.JSONObject;
import com.bxs.rbac.shiro.jwt.common.AbstractBaseController;
import com.bxs.rbac.shiro.jwt.common.ApiResultCode;
import com.bxs.rbac.shiro.jwt.domain.entity.User;
import com.bxs.rbac.shiro.jwt.service.token.TokenService;
import com.bxs.rbac.shiro.jwt.service.user.UserService;
import com.bxs.rbac.shiro.jwt.utils.ShiroUtils;
import com.bxs.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *
 * </p>
 *
 * @Author: Mr.Lu
 * @Since: 2020/6/17 17:48
 */
@RestController
@RequiredArgsConstructor
public class LoginController extends AbstractBaseController {
    private static final Logger _logger = LoggerFactory.getLogger(LoginController.class);

    private final TokenService tokenService;
    private final UserService userService;

    @GetMapping("/login")
    public ApiResponse login(User user) throws Exception{
        _logger.info("用户请求登录获取Token");

        String password = ShiroUtils.md5(user.getPassword(), user).toUpperCase();

        user = userService.findUserByUsername( user.getUsername() );

        if(null == user){
            throw new UnknownAccountException();
        }

        if(!user.getPassword().equals(password)){
            throw new IncorrectCredentialsException();
        }

        // 状态:  1-正常 2-锁定  3-禁用 4-异常
        switch ( user.getStatus() ) {
            case LOCKED:
                throw new LockedAccountException();
            case Disabled:
                throw new DisabledAccountException();
            default:
        }

        String generate = tokenService.generate(user);
        _logger.info("token : " + generate);

        return ApiResponse.success(new JSONObject().put("token", generate));
    }

    /**
     * 退出
     * @return
     */
    @PostMapping("/logout")
    public ApiResponse logout(){
        _logger.info("退出");
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return ApiResponse.message("退出成功");
    }


    @GetMapping(path = "/401")
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ApiResponse unauthorized() {
        return ApiResponse.fail(ApiResultCode.ERROR.code, "Unauthorized");
    }
}
